package cn.itcast.controller;


import cn.itcast.SysLog;
import cn.itcast.service.SysLogService;
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIConversion;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;


@Component
@Aspect
public class LogAop {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private SysLogService sysLogService;

    private Date visitTime;//访问的时间

    private Class clazz;//访问的类

    private Method method; //访问的方法
        //"execution(* com.itheima.ssm.controller.*.*(..))"
    //前置通知，主要作用是获取访问的时间，访问的类和执行的方法。
    @Before("execution(* cn.itcast.controller.*.*(..))")
    public void doBefore(JoinPoint jp) throws  Exception{
        visitTime = new Date();//获取访问的时间
         clazz =  jp.getTarget().getClass();//获取访问的类

        MethodSignature methodSignature = (MethodSignature)jp.getSignature(); //获取切入后的信息，
         method = methodSignature.getMethod();//获取执行的方法。


    }

    //后置通知

    @After("execution(* cn.itcast.controller.*.*(..))")
    public void doAfter() throws Exception{
        //获取访问的时长
        Long time = new Date().getTime()-visitTime.getTime();

        //获取URL
        String URL = request.getRequestURI();

        //获取访问的ip
        String IP = request.getRemoteAddr();

        //获取操作的当前用户
        SecurityContext context = SecurityContextHolder.getContext();
        User user = (User) context.getAuthentication().getPrincipal();
        String username = user.getUsername();

        //封装日志对象
        SysLog sysLog = new SysLog();
        sysLog.setVisitTime(visitTime);
        sysLog.setExecutionTime(time);
        sysLog.setIp(IP);
        sysLog.setUrl(URL);
        sysLog.setUsername(username);
        sysLog.setMethod("类名为："+clazz.getName()+" 方法名为："+method.getName());
        //将日志对象存进数据库。

        sysLogService.save(sysLog);


    }

}
